package com.yunxin.admin.system.api.core.merchant;

import com.yunxin.admin.system.infra.common.constant.SecurityConstants;
import com.yunxin.admin.system.infra.framework.resubmit.Resubmit;
import com.yunxin.admin.system.infra.framework.security.util.SecurityUtils;
import com.yunxin.admin.system.infra.framework.syslog.AutoLog;
import com.yunxin.common.result.PageResult;
import com.yunxin.common.result.Result;
import com.yunxin.core.application.command.merchant.AddMerchantCommand;
import com.yunxin.core.application.command.merchant.MerchantPageCommand;
import com.yunxin.core.application.command.merchant.UpdateMerchantCommand;
import com.yunxin.core.application.command.merchant.UpdateMerchantStatusCommand;
import com.yunxin.core.application.dto.merchant.MerchantDetailDTO;
import com.yunxin.core.application.dto.merchant.MerchantListDTO;
import com.yunxin.core.application.dto.merchant.MerchantPageDTO;
import com.yunxin.core.application.dto.user.UserInfoPageDTO;
import com.yunxin.core.application.service.MerchantApplicationAdminService;
import com.yunxin.core.application.service.MerchantQueryAdminService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.List;

/**
 * @author zero°
 * @since 2023-05-29
 */
@Tag(name = "21.商户管理")
@Slf4j
@RestController
@RequestMapping("/core/v1/merchant")
@RequiredArgsConstructor
public class MerchantController {

    private final MerchantApplicationAdminService merchantApplicationAdminService;

    private final MerchantQueryAdminService merchantQueryAdminService;

    @Operation(summary = "新增商户", security = {@SecurityRequirement(name = SecurityConstants.TOKEN_KEY)})
    @PostMapping("/addMerchant")
    @PreAuthorize("@ss.hasPerm('core:merchant:add')")
    @Resubmit
    @AutoLog(value = "新增商户")
    public Result<Boolean> addMerchant(@Validated @RequestBody AddMerchantCommand command) {
        command.setCreator(SecurityUtils.X.getUser().getUsername());
        return Result.success(merchantApplicationAdminService.addMerchant(command));
    }

    @Operation(summary = "更新商户", security = {@SecurityRequirement(name = SecurityConstants.TOKEN_KEY)})
    @PostMapping("/updateMerchant")
    @PreAuthorize("@ss.hasPerm('core:merchant:edit')")
    @Resubmit
    @AutoLog(value = "更新商户")
    public Result<Boolean> updateMerchant(@Validated @RequestBody UpdateMerchantCommand command) {
        command.setEditor(SecurityUtils.X.getUser().getUsername());
        return Result.success(merchantApplicationAdminService.updateMerchant(command));
    }

    @Operation(summary = "更新商户状态", security = {@SecurityRequirement(name = SecurityConstants.TOKEN_KEY)})
    @PostMapping("/updateMerchantStatus")
    @PreAuthorize("@ss.hasPerm('core:merchant:status:edit')")
    @Resubmit
    @AutoLog(value = "更新商户状态")
    public Result<Boolean> updateMerchantStatus(@Validated @RequestBody UpdateMerchantStatusCommand command) {
        command.setEditor(SecurityUtils.X.getUser().getUsername());
        return Result.success(merchantApplicationAdminService.updateMerchantStatus(command));
    }

    @Operation(summary = "根据id获取商户信息", security = {@SecurityRequirement(name = SecurityConstants.TOKEN_KEY)})
    @GetMapping("/getMerchantDetail/{id}")
    public Result<MerchantDetailDTO> getMerchantDetail(@Parameter(description = "商户id") @PathVariable Long id) {
        MerchantDetailDTO result = merchantQueryAdminService.getMerchantDetail(id);
        return Result.success(result);
    }

    @Operation(summary = "获取商户下拉列表(可根据商户类型区分)", security = {@SecurityRequirement(name = SecurityConstants.TOKEN_KEY)})
    @GetMapping("/listMerchant")
    public Result<List<MerchantListDTO>> listMerchant(@Parameter(description = "商户类型") @RequestParam(value = "merchantType", required = false) Integer merchantType) {
        List<MerchantListDTO> result = merchantQueryAdminService.listMerchant(merchantType);
        return Result.success(result);
    }

    @Operation(summary = "分页查询商户列表", security = {@SecurityRequirement(name = SecurityConstants.TOKEN_KEY)})
    @PostMapping("/merchantPageQuery")
    public PageResult<MerchantPageDTO> merchantPageQuery(@Validated @RequestBody MerchantPageCommand command) {
        return merchantQueryAdminService.merchantPageQuery(command);
    }

    @Operation(summary = "分页查询商户列表-导出", security = {@SecurityRequirement(name = SecurityConstants.TOKEN_KEY)})
    @PostMapping("/export")
    public ResponseEntity<byte[]> export(@Validated @RequestBody MerchantPageCommand command) throws IOException {
        List<MerchantPageDTO> list = merchantQueryAdminService.merchantPageQueryList(command);

        // 创建工作簿
        Workbook workbook = new XSSFWorkbook();
        // 创建工作表
        Sheet sheet = workbook.createSheet("Sheet1");

        // 创建标题行
        Row headerRow = sheet.createRow(0);
        // 设置表头
        headerRow.createCell(0).setCellValue("创建时间");
        headerRow.createCell(1).setCellValue("商户类型");
        headerRow.createCell(2).setCellValue("商户名称");
        headerRow.createCell(3).setCellValue("负责人");
        headerRow.createCell(4).setCellValue("手机号");
        headerRow.createCell(5).setCellValue("微信号");
        headerRow.createCell(6).setCellValue("合作状态");

        // 填充数据 从第二行开始
        int rowNum = 1;
        for (MerchantPageDTO dto : list) {
            // 将Date对象格式化为指定格式的字符串
            SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String createTime = "";
            if(dto.getCreateTime()!=null){
                createTime  = outputFormat.format(dto.getCreateTime());

            }
            // 将Date对象格式化为指定格式的字符串
            Row row = sheet.createRow(rowNum);
            row.createCell(0).setCellValue(createTime);
            row.createCell(1).setCellValue(dto.getMerchantType());
            row.createCell(2).setCellValue(dto.getMerchantName());
            row.createCell(3).setCellValue(dto.getResponsiblePerson());
            row.createCell(4).setCellValue(dto.getResponsiblePerson());
            if(dto.getWechatNumber()!=null){
                row.createCell(5).setCellValue(dto.getWechatNumber());
            }
            rowNum ++ ;
        }
        // 将工作簿写入 ByteArrayOutputStream
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        workbook.write(byteArrayOutputStream);

        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentDispositionFormData("attachment", URLEncoder.encode("分页查询商户列表", StandardCharsets.UTF_8.toString()) + ".xlsx");
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

        // 返回 Excel 文件的字节数组
        return new ResponseEntity<>(byteArrayOutputStream.toByteArray(), headers, HttpStatus.OK);
    }


}
